<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=0, viewport-fit=cover" />
	<title>double-link-list</title>
</head>
<body>
<script>
// 张三  <-->  李四  <-->  王五
class LinkNode {
	constructor(value) {
		this.value = value;
		this.next = null;
		this.prev = null;
	}
}

class DoubleLinkList {
	constructor(value) {
		if (value) {
			this.head = new LinkNode(value)
			this.size = 1;
		}
		else {
			this.head = null;
			this.size = 0;
		}
	}

	getSize() {
		return this.size;
	}

	pushNode(value) {
		const newNode = new LinkNode(value);
		if (!this.head) {
			this.head = newNode;
		}
		else {
			let currentNode = this.head;
			while (currentNode.next) {
				currentNode = currentNode.next;
			}
			currentNode.next = newNode;
			newNode.prev = currentNode;
		}

		this.size++;
	}

	searchNode(index) {
		if (index < 0 || index >= this.size) return null;
		let currentNode = this.head;
		let i = 0;
		while (i < index) {
			currentNode = currentNode.next;
			i++;
		}
		return currentNode;
	}

	insertNode(index, value) {
		if (index < 0 || index > this.size) return;
		const newNode = new LinkNode(value);
		if (index === 0) {
			newNode.next = this.head;
			this.head.prev = newNode;
			this.head = newNode;
			this.size++;
		}
		if (index === this.size) {
			this.pushNode(value)
		}
		else {
			const currentNode = this.searchNode(index)
			const prevNode = currentNode.prev;
			prevNode.next = newNode;
			newNode.prev = prevNode;
			newNode.next = currentNode;
			currentNode.prev = newNode;
			this.size++;
		}


		return newNode;
	}

	removeNode(index) {
		if (index < 0 || index >= this.size) return null;
		const findNode = this.searchNode(index)
		// 头
		if (index === 0) {
			const currentNode = this.head;
			const nextNode = currentNode.next;
			currentNode.next = null;
			nextNode.prev = null;
			this.head = nextNode;
		}
		// 尾
		if (index === this.size - 1) {
			const currentNode = this.searchNode(index)
			const prevNode = currentNode.prev;
			prevNode.next = null;
			currentNode.prev = null;
		}
		// 中间
		else {
			const currentNode = this.searchNode(index)
			const prevNode = currentNode.prev;
			const nextNode = currentNode.next;
			prevNode.next = nextNode;
			nextNode.prev = prevNode;
			currentNode.next = null;
			currentNode.prev = null;
		}

		this.size--;
		return findNode;
	}

	reverseList() {
		if (this.size <= 1) return this;
		let currentNode = this.head;
		let prevNode = null;
		let nextNode = currentNode.next;
		while (currentNode) {
			currentNode.next = prevNode;
			currentNode.prev = nextNode;

			prevNode = currentNode;
			currentNode = nextNode;
			if (currentNode) {
				nextNode = currentNode.next;
			}
			else {
				this.head = prevNode;
			}
		}
		return this;
	}

	toArr() {
		const list = [];
		let currentNode = this.head;
		while (currentNode) {
			list.push(currentNode.value);
			currentNode = currentNode.next;
		}
		return list;
	}

	toString() {
		return this.toArr().join(' <--> ')
	}

}

const doubleLinkList = new DoubleLinkList('甲');
doubleLinkList.pushNode('乙')
doubleLinkList.pushNode('丙')
doubleLinkList.pushNode('丁')

// console.log(`doubleLinkList.searchNode---`, doubleLinkList.searchNode(3))
// console.log(doubleLinkList.insertNode(1, '超人'));
// console.log(`doubleLinkList.removeNode---`, doubleLinkList.removeNode(1))
// console.log(`doubleLinkList.reverseList-----`, doubleLinkList.reverseList());
// console.log(`doubleLinkList.toArr--`, doubleLinkList.toArr())
console.log(`doubleLinkList.toArr--`, doubleLinkList.toString())
console.log(`doubleLinkList---`, doubleLinkList)
</script>
</body>
</html>
